package com.share.utils;

import cn.hutool.crypto.CryptoException;
import com.share.properties.EncryptionProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Slf4j
@Component
public class CryptoUtils {
    private final EncryptionProperties properties;

    public CryptoUtils(EncryptionProperties properties) {
        this.properties = properties;
        validateConfig();
    }

    private void validateConfig() {
        if (properties.getKey() == null || properties.getKey().length() < 16) {
            throw new IllegalStateException("加密密钥未配置或长度不足16字节");
        }
        if (properties.getIv() == null || properties.getIv().length() < 16) {
            throw new IllegalStateException("加密IV未配置或长度不足16字节");
        }
    }

    /**
     * 解密AES加密的字符串
     * @param encryptedText Base64编码的加密字符串
     * @return 解密后的原文
     */
    public String decrypt(String encryptedText) {
        try {
            // 参数校验
            if (encryptedText == null || encryptedText.trim().isEmpty()) {
                throw new IllegalArgumentException("加密文本不能为空");
            }

            // 解码Base64
            byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText.trim());

            // 创建密钥和IV
            SecretKeySpec keySpec = new SecretKeySpec(
                    properties.getKey().getBytes(StandardCharsets.UTF_8),
                    properties.getKeyAlgorithm()
            );
            IvParameterSpec ivSpec = new IvParameterSpec(
                    properties.getIv().getBytes(StandardCharsets.UTF_8)
            );

            // 初始化解密器
            Cipher cipher = Cipher.getInstance(properties.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            // 执行解密
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

            // 转换为字符串
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (IllegalArgumentException e) {
            log.error("解密参数错误: {}", e.getMessage());
            throw new CryptoException("解密参数错误", e);
        } catch (Exception e) {
            log.error("解密失败: {}", e.getMessage());
            throw new CryptoException("解密失败", e);
        }
    }

    /**
     * 加密字符串
     * @param plainText 原文
     * @return Base64编码的加密字符串
     */
    public String encrypt(String plainText) {
        try {
            // 参数校验
            if (plainText == null || plainText.trim().isEmpty()) {
                throw new IllegalArgumentException("原文不能为空");
            }

            // 创建密钥和IV
            SecretKeySpec keySpec = new SecretKeySpec(
                    properties.getKey().getBytes(StandardCharsets.UTF_8),
                    properties.getKeyAlgorithm()
            );
            IvParameterSpec ivSpec = new IvParameterSpec(
                    properties.getIv().getBytes(StandardCharsets.UTF_8)
            );

            // 初始化加密器
            Cipher cipher = Cipher.getInstance(properties.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

            // 执行加密
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

            // 转换为Base64
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (IllegalArgumentException e) {
            log.error("加密参数错误: {}", e.getMessage());
            throw new CryptoException("加密参数错误", e);
        } catch (Exception e) {
            log.error("加密失败: {}", e.getMessage());
            throw new CryptoException("加密失败", e);
        }
    }
}